package cn.tedu.fresheveryday.service.impl;

import cn.tedu.fresheveryday.exception.ServiceException;
import cn.tedu.fresheveryday.mapper.*;
import cn.tedu.fresheveryday.pojo.dto.OrderPagerDTO;
import cn.tedu.fresheveryday.pojo.entity.*;
import cn.tedu.fresheveryday.pojo.vo.OrderListVO;
import cn.tedu.fresheveryday.pojo.vo.OrderSimpleOrderIdAndDistIdVO;
import cn.tedu.fresheveryday.pojo.vo.OrderSimpleOrderIdAndUserIdVO;
import cn.tedu.fresheveryday.pojo.vo.ShopCartVO;
import cn.tedu.fresheveryday.restful.ResponseCode;
import cn.tedu.fresheveryday.service.IOrderService;
import cn.tedu.fresheveryday.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class OrderServiceImpl implements IOrderService {
    private final OrderMapper mapper;
    private final ShopCartMapper cartMapper;
    private final SubOrderMapper orderMapper;
    private final ProductMapper productMapper;
    private final UserReceiveInfoMapper userReceiveInfoMapper;
    private final OrderDistributionMapper orderDistributionMapper;
    private final OrderStatusHistoryMapper orderStatusHistoryMapper;

    @Autowired
    public OrderServiceImpl(OrderMapper mapper, ShopCartMapper cartMapper, SubOrderMapper orderMapper,
            ProductMapper productMapper, UserReceiveInfoMapper userReceiveInfoMapper,
            OrderDistributionMapper orderDistributionMapper, OrderStatusHistoryMapper orderStatusHistoryMapper) {
        this.mapper = mapper;
        this.cartMapper = cartMapper;
        this.orderMapper = orderMapper;
        this.productMapper = productMapper;
        this.userReceiveInfoMapper = userReceiveInfoMapper;
        this.orderDistributionMapper = orderDistributionMapper;
        this.orderStatusHistoryMapper = orderStatusHistoryMapper;
    }

    @Override // 根据购物车添加订单
    public void insert(Order order, ShopCart shopCart) {
        // 通过id获取收货信息
        UserReceiveInfo userReceiveInfo = userReceiveInfoMapper.selectById(order.getDistId());

        // 收货信息设置到配送信息
        OrderDistribution dist = new OrderDistribution();

        dist.setId(UUID.randomUUID().toString());
        dist.setReceiver(userReceiveInfo.getName());
        dist.setPhone(userReceiveInfo.getPhone());
        dist.setAddress(userReceiveInfo.getAddress());

        // 设置订单信息
        order.setState(1); // 设置订单状态
        order.setUpdateTimes(0); // 设置订单修改次数
        order.setDistId(dist.getId()); // 设置配送信息id
        order.setOrderId(StringUtils.uuid()); // 设置订单号
        order.setCreated(LocalDateTime.now()); // 设置订单创建时间

        // 设置订单状态更新信息
        OrderStatusHistory status = new OrderStatusHistory();

        status.setState(1);
        status.setOrderId(order.getOrderId());
        status.setUpdateTime(LocalDateTime.now());

        // 设置子订单信息
        SubOrder subOrder = new SubOrder();

        subOrder.setMoney(shopCart.getMoney()); // 设置购物车金额
        subOrder.setOrderId(order.getOrderId()); // 设置父订单号
        subOrder.setQuantity(shopCart.getQuantity()); // 设置商品数量
        subOrder.setProductId(shopCart.getProductId()); // 设置商品id

        // 1、保存订单信息
        mapper.insert(order);
        // 2、保存子订单
        orderMapper.insert(subOrder);
        // 3、保存配送信息
        orderDistributionMapper.insert(dist);
        // 4、保存订单状态历史
        orderStatusHistoryMapper.insert(status);
        // 5、删除用户的购物车
        cartMapper.deleteByUserId(order.getUserId());
    }

    // 生成订单
    @Override
    public void generate(Order order) {
        // 设置订单信息

        order.setOrderId(StringUtils.uuid()); // 设置订单号
        order.setCreated(LocalDateTime.now()); // 设置订单创建时间
        order.setUpdateTimes(0); // 设置订单修改次数
        order.setState(1); // 设置订单状态

        // 获取用户购物车
        List<ShopCartVO> shopCartVOList = cartMapper.selectByUserId(order.getUserId());
        // 通过id获取收货信息
        UserReceiveInfo receiveInfo = userReceiveInfoMapper.selectById(order.getDistId());

        // 从收货信息设置到配送信息
        OrderDistribution dist = new OrderDistribution();

        dist.setId(UUID.randomUUID().toString());
        dist.setReceiver(receiveInfo.getName());
        dist.setPhone(receiveInfo.getPhone());
        dist.setAddress(receiveInfo.getAddress());

        // 设置订单的配送信息id
        order.setDistId(dist.getId());

        // 设置订单状态更新信息
        OrderStatusHistory status = new OrderStatusHistory();

        status.setState(1);
        status.setUpdateTime(LocalDateTime.now());
        status.setOrderId(order.getOrderId());

        // 1、保存收货信息到配送信息
        orderDistributionMapper.insert(dist);
        // 2、保存订单信息
        mapper.insert(order);
        // 3、保存订单状态信息
        orderStatusHistoryMapper.insert(status);

        // 设置子订单信息，保存子订单信息
        List<SubOrder> list = new ArrayList<>();

        for (ShopCartVO shopCartVO : shopCartVOList) {
            SubOrder subOrder = new SubOrder();

            subOrder.setOrderId(order.getOrderId()); // 设置父订单号
            subOrder.setProductId(shopCartVO.getProductId()); // 设置商品id
            subOrder.setQuantity(shopCartVO.getQuantity()); // 设置商品数量
            subOrder.setMoney(shopCartVO.getMoney()); // 设置金额

            list.add(subOrder);
        }

        // 4、添加子订单（批量添加）
        orderMapper.insertList(list);
        // 5、删除用户的购物车
        cartMapper.deleteByUserId(order.getUserId());
    }

    // 根据id删除订单
    @Override
    public void deleteById(int id) {
        // 通过id查询订单的订单号和配送id
        OrderSimpleOrderIdAndDistIdVO orderSimpleOrderIdAndDistIdVO = mapper.selectById(id);
        // 得到订单号
        String orderId = orderSimpleOrderIdAndDistIdVO.getOrderId();

        // 1、删除订单
        mapper.deleteById(id);
        // 2、通过父订单号删除子订单
        orderMapper.deleteByOrderId(orderId);
        // 3、删除订单状态历史
        orderStatusHistoryMapper.deleteByOrderId(orderId);
        // 4、删除订单配送信息
        orderDistributionMapper.deleteById(orderSimpleOrderIdAndDistIdVO.getDistId());
    }

    // 根据用户id分页查询订单
    @Override
    public List<OrderListVO> selectByUserId(OrderPagerDTO orderPagerDTO) {
        return mapper.selectByUserId(orderPagerDTO);
    }

    // 根据用户id查询订单数量
    @Override
    public int selectCountByUserId(String userId) {
        return mapper.selectCountByUserId(userId);
    }

    // 根据订单状态和用户id分页查询订单
    @Override
    public List<OrderListVO> selectByStateAndUserId(OrderPagerDTO orderPagerDTO) {
        return mapper.selectByStateAndUserId(orderPagerDTO);
    }

    // 根据订单状态和用户id查询订单数量
    @Override
    public int selectCountByStateAndUserId(int state, String userId) {
        return mapper.selectCountByStateAndUserId(state, userId);
    }

    // 修改订单状态为已付款
    @Override
    public void pay(Integer id) {
        updateStateById(id, 2); // 修改订单状态为2，已付款
    }

    // 修改订单状态为配送中
    @Override
    public void distribute(Integer id) {
        updateStateById(id, 3); // 修改订单状态为3，配送中
    }

    // 修改订单状态为已送达
    @Override
    public void arrive(Integer id) {
        updateStateById(id, 4); // 修改订单状态为4，已送达
    }

    // 确认收货
    @Override
    public void receipt(Integer id) {
        updateStateById(id, 5); // 修改订单状态为5，已收货
    }

    // 取消订单
    @Override
    public void cancel(int id) {
        // 通过id查询订单号
        String orderId = mapper.selectOrderIdById(id);

        // 设置订单状态历史
        OrderStatusHistory orderStatusHistory = new OrderStatusHistory();

        orderStatusHistory.setOrderId(orderId);
        orderStatusHistory.setUpdateTime(LocalDateTime.now());
        orderStatusHistory.setState(6);

        // 1、保存订单状态历史
        orderStatusHistoryMapper.insert(orderStatusHistory);
        // 2、修改订单状态为6，已取消
        mapper.updateStateById(id, 6);

        // 3、恢复订单中商品的库存
        // 根据父订单号查询子订单
        List<SubOrder> subOrderList = orderMapper.selectByOrderId(orderId);

        for (SubOrder subOrder : subOrderList) {
            // 得到子订单的商品id
            int productId = subOrder.getProductId();
            // 根据id查询商品信息
            int quantity = productMapper.selectQuantityById(productId);

            // 恢复商品库存
            productMapper.updateQuantityById(
                    productId, // 商品id
                    // 新的商品数量 = 商品数量 + 子订单的商品数量
                    quantity + subOrder.getQuantity()
            );
        }
    }

    @Override
    public void again(Integer id) {
        // 通过id查询订单的“订单号“和”用户id”
        OrderSimpleOrderIdAndUserIdVO order = mapper.selectSimpleById(id);

        // 订单不存在，抛出异常
        if (order == null) {
            throw new ServiceException(ResponseCode.BAD_REQUEST, "操作失败，订单不存在");
        }

        // 通过订单号查询子订单信息
        List<SubOrder> subOrderList = orderMapper.selectByOrderId(order.getOrderId());
        // 子订单的商品添加到购物车
        List<ShopCart> list = new ArrayList<>();

        for(SubOrder subOrder : subOrderList) {
            Integer quantity = subOrder.getQuantity();
            Integer productId = subOrder.getProductId();

            ShopCart shopCart = new ShopCart();

            shopCart.setId(UUID.randomUUID().toString());
            shopCart.setUserId(order.getUserId()); // 设置用户id
            shopCart.setCreated(LocalDateTime.now()); // 设置添加时间
            shopCart.setQuantity(subOrder.getQuantity()); // 设置商品数量
            shopCart.setProductId(productId); // 设置商品id
            shopCart.setMoney(subOrder.getMoney() * quantity); // 设置购物车金额

            list.add(shopCart);

            // 减少商品库存
            // 根据商品id查询商品库存
            int productQuantity = productMapper.selectQuantityById(productId);

            productMapper.updateQuantityById(productId, productQuantity - quantity);
        }

        // 添加购物车
        cartMapper.insertList(list);
    }

    /**
     * 通过订单id修改订单状态
     * @param id 订单id
     * @param state 订单状态
     */
    @Transactional
    public void updateStateById(Integer id, Integer state) {
        // 通过id查询订单信号
        String orderId = mapper.selectOrderIdById(id);

        // 设置订单状态历史
        OrderStatusHistory orderStatusHistory = new OrderStatusHistory();

        orderStatusHistory.setUpdateTime(LocalDateTime.now());
        orderStatusHistory.setOrderId(orderId);
        orderStatusHistory.setState(state);

        // 保存订单状态历史
        orderStatusHistoryMapper.insert(orderStatusHistory);
        // 修改订单状态为state
        mapper.updateStateById(id, state);
    }

}
